import os
import pickle
from collections import OrderedDict
from typing import Any, Optional

class FileMemoryCache:
    """
    文件+内存二级缓存模块
    
    特性:
    1. 通过路径初始化缓存目录
    2. 文件缓存永久保存
    3. 内存缓存使用LRU策略管理
    4. 可设置内存缓存最大容量
    """
    
    def __init__(self, cache_dir: str, max_memory_size: int = 100):
        """
        初始化缓存模块
        
        :param cache_dir: 缓存文件存储目录
        :param max_memory_size: 内存缓存最大条目数
        """
        self.cache_dir = cache_dir
        self.max_memory_size = max_memory_size
        self.memory_cache = OrderedDict()
        
        # 确保缓存目录存在
        os.makedirs(self.cache_dir, exist_ok=True)
    
    def _get_cache_path(self, key: str) -> str:
        """获取缓存文件路径"""
        return os.path.join(self.cache_dir, f"{key}.cache")
    
    def set(self, key: str, value: Any) -> None:
        """
        设置缓存
        
        :param key: 缓存键
        :param value: 缓存值
        """
        # 更新内存缓存
        self.memory_cache[key] = value
        
        # 如果超过最大内存大小，移除最老的条目
        if len(self.memory_cache) > self.max_memory_size:
            self.memory_cache.popitem(last=False)
        
        # 持久化到文件
        cache_path = self._get_cache_path(key)
        with open(cache_path, 'wb') as f:
            pickle.dump(value, f)
    
    def get(self, key: str) -> Optional[Any]:
        """
        获取缓存
        
        :param key: 缓存键
        :return: 缓存值，如果不存在返回None
        """
        # 首先检查内存缓存
        if key in self.memory_cache:
            # 更新访问顺序
            value = self.memory_cache.pop(key)
            self.memory_cache[key] = value
            return value
        
        # 检查文件缓存
        cache_path = self._get_cache_path(key)
        if os.path.exists(cache_path):
            try:
                with open(cache_path, 'rb') as f:
                    value = pickle.load(f)
                    # 加载到内存缓存
                    self.memory_cache[key] = value
                    return value
            except (pickle.PickleError, EOFError):
                return None
        
        return None
    
    def clear_memory_cache(self) -> None:
        """清空内存缓存"""
        self.memory_cache.clear()
    
    def get_memory_cache_size(self) -> int:
        """获取当前内存缓存大小"""
        return len(self.memory_cache)